﻿#region usings
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using InsuranceAdjuster.OccasionallyConnected;
using InsuranceAdjuster.OccasionallyConnected.Messages;
using InsuranceAdjuster.Services;
using InsuranceAdjuster.Web.Models;
#endregion
namespace InsuranceAdjuster.Helpers {
    public class VinHelper : INotifyPropertyChanged {
        private VehicleInformation _VehicleInformation = null;

        private Guid _CallerGuid = Guid.NewGuid();
        private EntityManager _EntityManager = EntityManager.Current;
        private ObservableCollection<int> _vehicleYears = new ObservableCollection<int>();
        private ObservableCollection<string> _vehicleMakes = new ObservableCollection<string>();
        private ObservableCollection<string> _vehicleModels = new ObservableCollection<string>();
        private int? _SelectedYear;
        private String _SelectedMake;
        private String _SelectedModel;
        private String _SelectedVin;
        private int? _previousYear;
        private string _previousMake;
        private string _previousModel;
        private byte[] _SelectedVehiclePhoto;
        private Claim _SelectedClaim;

        public VinHelper() {
            _EntityManager.EntityChanged += EntityManager_EntityChanged;
            _EntityManager.ProcessMessage(new GetVehicleInformationMessage());
        }



        public int? SelectedYear {
            get { return _SelectedYear; }
            set {
                if (_SelectedYear == value)
                    return;
                _SelectedYear = value;
                RaisePropertyChanged("SelectedYear");
                LoadVehicleMakes();
            }
        }
        public String SelectedMake {
            get { return _SelectedMake; }
            set {
                if (_SelectedMake == value)
                    return;
                _SelectedMake = value;
                RaisePropertyChanged("SelectedMake");
                LoadVehicleModels();
            }
        }
        public String SelectedModel {
            get { return _SelectedModel; }
            set {
                if (_SelectedModel == value)
                    return;
                _SelectedModel = value;
                RaisePropertyChanged("SelectedModel");
                LoadVehicleImage();
            }
        }
        public String SelectedVin {
            get { return _SelectedVin; }
            set {
                if (_SelectedVin == value)
                    return;
                _SelectedVin = value;
                RaisePropertyChanged("SelectedVin");
                ParseVIN();
            }
        }
        public byte[] SelectedVehiclePhoto {
            get { return _SelectedVehiclePhoto; }
            private set {
                _SelectedVehiclePhoto = value;
                RaisePropertyChanged("SelectedVehiclePhoto");
            }
        }
        public Guid? SelectedVehiclePhotoGuid { get; private set; }
        public ObservableCollection<int> VehicleYears {
            get { return _vehicleYears; }
            set {
                if (value != _vehicleYears) {
                    _vehicleYears = value;
                    RaisePropertyChanged("VehicleYears");
                }
            }
        }
        public ObservableCollection<string> VehicleMakes {
            get { return _vehicleMakes; }
            set {
                if (value != _vehicleMakes) {
                    _vehicleMakes = value;
                    RaisePropertyChanged("VehicleMakes");
                }
            }
        }
        public ObservableCollection<string> VehicleModels {
            get { return _vehicleModels; }
            set {
                if (value != _vehicleModels) {
                    _vehicleModels = value;
                    RaisePropertyChanged("VehicleModels");
                }
            }
        }
        public Claim SelectedClaim {
            get { return _SelectedClaim; }
            set {
                if (_SelectedClaim == value)
                    return;

                if (_SelectedClaim != null)
                    _SelectedClaim.PropertyChanged -= new PropertyChangedEventHandler(Claim_PropertyChanged);

                _SelectedClaim = value;
                _SelectedClaim.PropertyChanged += new PropertyChangedEventHandler(Claim_PropertyChanged);

                _previousYear = SelectedClaim.InsuredYear;
                _previousMake = SelectedClaim.InsuredMake;
                _previousModel = SelectedClaim.InsuredModel;
                SelectedVin = SelectedClaim.InsuredVIN;
                SelectedYear = SelectedClaim.InsuredYear;
                SelectedMake = SelectedClaim.InsuredMake;
                SelectedModel = SelectedClaim.InsuredModel;
            }
        }

        private void Claim_PropertyChanged(object sender, PropertyChangedEventArgs e) {
            switch (e.PropertyName) {
                case "InsuredVIN":
                    SelectedVin = SelectedClaim.InsuredVIN;
                    break;
                case "InsuredYear":
                    SelectedYear = SelectedClaim.InsuredYear;
                    break;
                case "InsuredMake":
                    SelectedMake = SelectedClaim.InsuredMake;
                    break;
                case "InsuredModel":
                    SelectedModel = SelectedClaim.InsuredModel;
                    break;
                default:
                    break;
            }
        }
        private void EntityManager_EntityChanged(Guid entityGuid, Type entityType, ChangeOperation changeOperation, Origin changeOrigin, IEntity entity) {
            if (_VehicleInformation == null
                && entityType == typeof(VehicleInformation)) {

                _VehicleInformation = entity as VehicleInformation;
                LoadVehicleYears();
            }
            else if (entityGuid == SelectedVehiclePhotoGuid) {
                SelectedVehiclePhoto = (entity as VehicleReferencePhoto).PhotoData;               
            }
        }
        private void LoadVehicleYears() {
            if (_VehicleInformation == null)
                VehicleYears.Clear();
            else
                VehicleYears = _VehicleInformation.StandardVehicleImages
                                                  .Select(x => x.Year)
                                                  .Distinct()
                                                  .OrderBy(x => x)
                                                  .ToObservableCollection();
            if (_previousYear != null && VehicleYears.Contains((int) _previousYear)) {
                SelectedYear = _previousYear;
                LoadVehicleMakes();
            }
            RaisePropertyChanged("VehicleYears");
        }
        private void LoadVehicleMakes() {
            if (SelectedYear == null || _VehicleInformation == null)
                VehicleMakes.Clear();
            else {
                VehicleMakes = _VehicleInformation.StandardVehicleImages
                                                  .Where(x => x.Year == SelectedYear)
                                                  .Select(x => x.Make)
                                                  .Distinct()
                                                  .OrderBy(x => x)
                                                  .ToObservableCollection();
            }
            if (this.VehicleMakes.Contains(_previousMake)) {
                SelectedMake = _previousMake;
                LoadVehicleModels();
            }
            RaisePropertyChanged("VehicleMakes");
        }
        private void LoadVehicleModels() {
            if (SelectedYear == null || String.IsNullOrEmpty(SelectedMake) || _VehicleInformation == null)
                VehicleModels.Clear();
            else
                VehicleModels = _VehicleInformation.StandardVehicleImages
                                                   .Where(x => x.Year == SelectedYear
                                                            && x.Make.Equals(SelectedMake))
                                                   .Select(x => x.Model)
                                                   .Distinct()
                                                   .OrderBy(x => x)
                                                   .ToObservableCollection();
            if (VehicleModels.Contains(_previousModel)) {
                SelectedModel = _previousModel;
            }
            RaisePropertyChanged("VehicleModels");
            LoadVehicleImage();
        }
        private void LoadVehicleImage() {
            if (_VehicleInformation == null) {
                SelectedVehiclePhoto = null;
                RaisePropertyChanged("SelectedVehiclePhotoGuid");
                return;
            }

            if (SelectedYear == null
                || String.IsNullOrEmpty(SelectedMake)
                || String.IsNullOrEmpty(SelectedModel)) {
                SelectedVehiclePhoto = null;
            }
            else {
                SelectedVehiclePhotoGuid = _VehicleInformation.StandardVehicleImages
                                                              .Where(x => x.Year == (int)SelectedYear 
                                                                       && x.Make == SelectedMake
                                                                       && x.Model == SelectedModel)
                                                              .Select(x => x.ReferencePhotoGuid)
                                                              .FirstOrDefault();
                if (SelectedVehiclePhotoGuid == null)
                    SelectedVehiclePhoto = null;                
                else
                {
                    var MyMessage = new GetVehiclePhotoMessage((int)SelectedYear, SelectedMake, SelectedModel, (Guid)SelectedVehiclePhotoGuid);
                    MyMessage.CallerGuid = _CallerGuid;

                    _EntityManager.ProcessMessage(MyMessage);
                }
                RaisePropertyChanged("SelectedVehiclePhotoGuid");
            }
        }
        private void ParseVIN() {
            Helpers.VinCarInfo carInfo = Helpers.VINParser.Parse(SelectedVin);
            SelectedYear = carInfo.Year;
            SelectedMake = carInfo.Make;
            SelectedModel = carInfo.Model;
        }

        #region INofityPropertyChanged

        public event PropertyChangedEventHandler PropertyChanged;
        protected void RaisePropertyChanged(String propertyName) {
            if (PropertyChanged != null)
                Deployment.Current.Dispatcher.BeginInvoke(() => PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName)));
        }

        #endregion

    }
}
